Type CabTunes
	
	Const NAME:String        = "CabTunes"
	Const VERSION_MAJOR:Int  = 0
	Const VERSION_MINOR:Int  = 0
	Const VERSION_BUILD:Int  = 2
	?MacOs
	Const ENVIRONMENT:String = "MacOS"
	Const DIRECTORY:String   = ".CabTunes"
	?Win32
	Const ENVIRONMENT:String = "Win32"
	Const DIRECTORY:String   = "CabTunes"
	?Linux
	Const ENVIRONMENT:String = "Linux"
	Const DIRECTORY:String   = ".CabTunes"
	?
	Const ID:String          = NAME ..
	                         + " " ..
	                         + VERSION_MAJOR ..
	                         + "." ..
	                         + VERSION_MINOR ..
	                         + "." ..
	                         + VERSION_BUILD ..
	                         + " (" ..
	                         + ENVIRONMENT ..
	                         + ")"

	Const DEFAULT_LIBRARY_LOADER:String    = "iTunes"
	Const DEFAULT_GUI_SPLASH:String        = "v0"
	Const DEFAULT_GUI_MAIN:String          = "v0"
	Const DEFAULT_TRACK_PLAYER:String      = "process"
	Const DEFAULT_CREDIT_MANAGER:String    = "freeplay"
	Const DEFAULT_JUKEBOX_OBSERVERS:String = ""

	Global userDir:String

	Function main()
		AppTitle = ID
		SetGraphicsDriver GLMax2DDriver()
		?MacOs
			userDir = GetEnv_("HOME") + "/" + DIRECTORY
		?Win32
			userDir = GetEnv_("HOMEPATH") + "/Application Data/" + DIRECTORY
		?Linux
			userDir = GetEnv_("HOME") + "/" + DIRECTORY
		?
		If FileType(userDir) = 0 Then
			CreateDir(userDir)
		End If
		If FileType(userDir) <> 2 Then
			Throw "Expecting " + userDir + " to be a directory."
		End If
		
		Local cfg:Configuration = Configuration.GetInstance()
		Local cfgStrategy:ConfigurationStorageStrategyFlatFile = New ConfigurationStorageStrategyFlatFile
		cfgStrategy.fileName = userDir + "/" + NAME + ".cfg"
		cfg.strategy = cfgStrategy
		cfg.Clear()
		cfg.Load()
		
		Local splash:GUI_Splash = GUI_SplashFactory.Fetch(cfg.Get("GUI.Splash", DEFAULT_GUI_SPLASH))
		If splash Then
			splash.Show()
		End If
		Local libLoader:LibraryLoader = LibraryLoaderFactory.Fetch(cfg.Get("LibraryLoader", DEFAULT_LIBRARY_LOADER))
		If splash Then
			libLoader.addObserver(splash)
		End If
		Local lib:Library = libLoader.Load()
		libLoader.clearObservers()
		libLoader = Null
				
		Local libExport:LibraryExport = New LibraryExportTextDump
		Local fp:TStream = WriteStream(userDir + "/library_export.txt") 
		libExport.Export(lib, fp)
		CloseStream(fp)
		libExport = Null
		fp        = Null
		
		' Setup jukebox
		Local creditMan:CreditManager = CreditManagerFactory.Fetch(cfg.Get("CreditManager", DEFAULT_CREDIT_MANAGER))
		Local tpBuilder:TrackPlayerBuilder = New TrackPlayerBuilder
		tpBuilder.strategy = TrackPlayerBuilderStrategyFactory.Fetch(cfg.Get("TrackPlayer", DEFAULT_TRACK_PLAYER))
		Local juke:Jukebox = Jukebox.Create(creditMan, tpBuilder)
		
		' load jukebox observers...
		Local obStr:String = cfg.Get("JukeboxObservers", DEFAULT_JUKEBOX_OBSERVERS)
		Local s:Int = 0
		Local e:Int = 0
		Local jo:JukeboxObserver
		While e < obStr.length
			If Chr(obStr[e]) = "," Then
				jo = JukeboxObserverFactory.Fetch(obStr[s..e].Trim())
				If jo Then
					juke.addObserver(jo)
				End If
				s=e + 1
			End If
			e:+1
		End While
		jo = JukeboxObserverFactory.Fetch(obStr[s..e].Trim())		
		If jo Then
			juke.addObserver(jo)
		End If
		
		' load Main GUI...		
		Local main:GUI_Main = GUI_MainFactory.Fetch(cfg.Get("GUI.Main", DEFAULT_GUI_MAIN)) 
		If splash Then
			splash.Hide()
			splash = Null
		End If
		If main Then
			main.run(userDir, juke, lib)
		Else
			RuntimeError("'Main' GUI component not loaded.")
		End If
		' make sure that we stop any music playing...
		If juke.current() Then
			juke.current().stop()
		End If
	End Function

End Type